package main.data.dataManager;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import de.gugubarra.core.nop.Nop;
import de.gugubarra.core.nop.Topic;
import de.gugubarra.core.nop.User;

import main.data.Centroid;
import main.data.Membership;

public class DataManagerSimpleImpl implements DataManager {
	private List<User> userList;
	private int numberOfUser = 100;

	private List<Topic> topicList;
	private int numberOfTopic = 10;

	private List<Nop> nopList;

	private List<Centroid> centroidList;
	private int numberOfCluster = 10;

	private List<Membership> membershipMatrix;

	public void initializeData() {
		userList = new ArrayList<User>();
		for (int i = 0; i < numberOfUser; i++) {
			User aUser = new User();
			aUser.setId(i);
			aUser.setName("User-" + i);
			userList.add(aUser);
		}

		topicList = new ArrayList<Topic>();
		for (int i = 0; i < this.numberOfTopic; i++) {
			Topic aTopic = new Topic();
			aTopic.setName("Topic-" + i);
			topicList.add(aTopic);
		}

		nopList = new ArrayList<Nop>();
		for (int i = 0; i < numberOfUser; i++) {
			Nop aNop = new Nop();
			aNop.setOwner(userList.get(i));
			double value = (1.0 * i) / (numberOfUser + 1);
			for (int j = 0; j < this.numberOfTopic; j++) {
				aNop.setTopicWeight(topicList.get(j), value);
			}
			nopList.add(aNop);
		}

		centroidList = new ArrayList<Centroid>();
		for (int i = 0; i < this.numberOfCluster; i++) {
			Centroid aCentroid = new Centroid();
			Nop aNop = nopList.get(i);
			HashMap<Topic, Double> topicWeightMap = getTopicWeightFromNop(aNop);
			aCentroid.setTopicWeightMap(topicWeightMap);
			centroidList.add(aCentroid);
		}

		membershipMatrix = new ArrayList<Membership>();
		for (int i = 0; i < this.numberOfCluster; i++) {
			Centroid aCentroid = this.centroidList.get(i);
			for (int j = 0; j < this.numberOfUser; j++) {
				Nop aNop = this.nopList.get(j);
				Membership aMembership = new Membership();
				aMembership.setCentroid(aCentroid);
				aMembership.setNop(aNop);
				aMembership.setMembershipValue(0.0);
				membershipMatrix.add(aMembership);
			}
		}
	}

	public HashMap<Topic, Double> getTopicWeightFromNop(Nop nop) {
		HashMap<Topic, Double> topicWeightMap = new HashMap<Topic, Double>();
		for (int i = 0; i < this.numberOfTopic; i++) {
			Topic aTopic = this.topicList.get(i);
			Double topicWeightValue = nop.getTopicWeight(aTopic);
			topicWeightMap.put(aTopic, topicWeightValue);
		}
		return topicWeightMap;
	}

	public void showAllData() {
		for (int i = 0; i < this.numberOfUser; i++) {
			for (int j = 0; j < this.numberOfTopic; j++) {
				System.out.print(this.nopList.get(i).getTopicWeight(
						this.topicList.get(j))
						+ " : ");
			}
			System.out.println();
		}
	}

	public List<User> getUserList() {
		return userList;
	}

	public void setUserList(List<User> userList) {
		this.userList = userList;
	}

	public int getNumberOfUser() {
		return numberOfUser;
	}

	public void setNumberOfUser(int numberOfUser) {
		this.numberOfUser = numberOfUser;
	}

	public int getNumberOfTopic() {
		return numberOfTopic;
	}

	public void setNumberOfTopic(int numberOfTopic) {
		this.numberOfTopic = numberOfTopic;
	}

	public List<Nop> getNopList() {
		return nopList;
	}

	public void setNopList(List<Nop> nopList) {
		this.nopList = nopList;
	}

	public List<Centroid> getCentroidList() {
		return centroidList;
	}

	public void setCentroidList(List<Centroid> centroidList) {
		this.centroidList = centroidList;
	}

	public int getNumberOfCluster() {
		return numberOfCluster;
	}

	public void setNumberOfCluster(int numberOfCluster) {
		this.numberOfCluster = numberOfCluster;
	}

	public List<Membership> getMembershipMatrix() {
		return membershipMatrix;
	}

	public void setMembershipMatrix(List<Membership> membershipMatrix) {
		this.membershipMatrix = membershipMatrix;
	}

	public void setTopicList(List<Topic> topicList) {
		this.topicList = topicList;
	}

	@Override
	public void addCluster(Centroid newCentroid) {
		// TODO Auto-generated method stub
		centroidList.add(newCentroid);
	}

	@Override
	public Centroid getCentroidByIndex(int indexOfCentroid) {
		// TODO Auto-generated method stub
		return this.centroidList.get(indexOfCentroid);
	}

	@Override
	public Membership getMembership(Nop nop, Centroid centroid) {
		// TODO Auto-generated method stub
		for (int i = 0; i < this.numberOfCluster * this.numberOfUser; i++) {
			if (this.membershipMatrix.get(i).getCentroid() == centroid) {
				if (this.membershipMatrix.get(i).getNop() == nop) {
					return this.membershipMatrix.get(i);
				}
			}
		}
		System.out.println("There is no such Membership!");
		return null;
	}

	@Override
	public Nop getNopByIndex(int indexOfNop) {
		// TODO Auto-generated method stub
		return this.nopList.get(indexOfNop);
	}

	@Override
	public List<Topic> getTopicList() {
		// TODO Auto-generated method stub
		return this.topicList;
	}

	@Override
	public User getUserByIndex(int indexOfUser) {
		// TODO Auto-generated method stub
		return userList.get(indexOfUser);
	}

	@Override
	public void mergeClusters(Centroid firstCentroid, Centroid secondCentroid) {
		// TODO Auto-generated method stub
		ArrayList<Nop> firstCluser = new ArrayList<Nop>();
		ArrayList<Nop> secondCluser = new ArrayList<Nop>();
		
		for (int i = 0; i < this.numberOfUser; i++) {
			Membership ms_1=this.getMembership(this.nopList.get(i), firstCentroid);
			Membership ms_2=this.getMembership(this.nopList.get(i), secondCentroid);
			ms_1.setMembershipValue(ms_1.getMembershipValue()+ ms_2.getMembershipValue());
			
		}
		
	}

	public void deleteCluster(Centroid centroid) {
		for (int i = 0; i < this.numberOfCluster * this.numberOfUser; i++) {
			if (this.membershipMatrix.get(i).getCentroid() == centroid) {
				this.membershipMatrix.remove(centroid);
			}
		}
	}

	@Override
	public void setCentroidByIndex(int indexOfCentroid, Centroid newCentroid) {
		// TODO Auto-generated method stub
		centroidList.set(indexOfCentroid, newCentroid);
	}

	@Override
	public void setMembership(Nop nop, Centroid centroid, Membership membership) {
		// TODO Auto-generated method stub
		for (int i = 0; i < this.numberOfCluster * this.numberOfUser; i++) {
			if (this.membershipMatrix.get(i).getCentroid() != centroid) {
				if (this.membershipMatrix.get(i).getNop() == nop) {
					this.membershipMatrix.get(i).setMembershipValue(
							membership.getMembershipValue());
				}
			}
		}
	}
}
